package com.um2.simplexe.serveur.ui.entryPoint;


import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.io.File;
import java.util.Vector;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;

import com.um2.simplexe.serveur.ui.exec.Methodes;
import com.um2.simplexe.serveur.ui.exec.ToutesLesMethodesServeur;
import com.um2.simplexe.serveur.ui.util.controleUI.InformationsSurApplication;
import com.um2.simplexe.serveur.ui.util.controleUI.InformationsSurApplicationServeur;
import com.um2.simplexe.serveur.ui.util.controleUI.actionsGeneriques.Evenements;
import com.um2.simplexe.serveur.ui.util.controleUI.chargeur.ChargeurLibrairie;
import com.um2.simplexe.serveur.ui.util.controleUI.chargeur.ChargeurMenu;
import com.um2.simplexe.serveur.ui.util.controleUI.chargeur.ChargeurPanneau;
import com.um2.simplexe.serveur.ui.util.controleUI.chargeur.menu.ControleurDeMenu;
import com.um2.simplexe.serveur.ui.util.controleUI.chargeur.menu.ControleurDePanneaux;
import com.um2.simplexe.serveur.ui.zone.Zone;


/**
 * 
 * Cette Classe est un Fenetre swing,
 * elle presente l'IHM de l'application du simplexe.
 * 
 * Elle est modulaire,
 * en particulier, on peut, a travers des plugins,
 * controler le contenu de la barre de menu.
 * 
 * Pour developper des plugins,
 * voir la documentation concernant le developpement
 * de plugins pour le client du Simplexe.
 * 
 * 03-02-2007
 * @author jean-marie codol
 *
 */
@SuppressWarnings("serial")
public class FenetreApplicationServeur extends JFrame {

	
	/**
	 * on supposera qu'a un instant t,
	 * on aura une seule instance de FenetreApplication.
	 * Donc on peut avoir un lien statique vers la fenetre.
	 * 
	 * cela facilitera la gestion des evenements,...
	 * 
	 * on pourra avoir acces a la fenetre a partir de
	 * methodes statiques, d'objets statiques,...
	 * 
	 */
	private static FenetreApplicationServeur instanceUnique ;
	
	private Methodes ensembleDeFonctions = new Methodes() ;
	private Thread ecouteThread = null ;
	
	
	
	public FenetreApplicationServeur() {
		super("Serveur de simplexe") ;
		FenetreApplicationServeur.instanceUnique = this ;
		

		/**********************************************************/
		/**********************************************************/
		/**********************************************************/
		/**********************************************************/

		
        ////////////////////////////////
		/// les librairies partagees ///
		////////////////////////////////
		
		
		// on verifie que le repertoire des librairies partagees est trouve
		boolean repertoireDesPluginsTrouve = false ;
		java.io.File repertoireLibrairies = new File(InformationsSurApplicationServeur.cheminVersLibrairies) ;
		if (repertoireLibrairies.exists())
		{
			repertoireDesPluginsTrouve = true ;
		}else
		{
			Evenements.warning("repertoire des librairies non trouve\n pour le chargement") ;
		}

		// on charge les librairies partagees
		if (repertoireDesPluginsTrouve)
		{
			// tout les fichiers dans le repertoire des librairies partagées
			String[] listeFile = repertoireLibrairies.list() ;
			// on prefixe pour obtenir un chemin complet
			for (int index=0;index<listeFile.length;index++) {
				listeFile[index]=repertoireLibrairies.getAbsolutePath()+java.io.File.separatorChar+listeFile[index] ;
			}
			
			// le chargeur de librairie
			ChargeurLibrairie chargeurDeLib = new ChargeurLibrairie() ;
			
			// on lui donne a manger la liste des fichiers potentiellement plugins
			chargeurDeLib.setFiles(listeFile) ;
			
			
			try {
				chargeurDeLib.chargerToutLesPlugins() ;
			} catch (Exception e) {
				Evenements.warning("erreur dans la recuperation des librairies : "+e.getMessage());
			} ;
			
			
		}
		
		
		
		
		
		

		/**********************************************************/
		/**********************************************************/
		/**********************************************************/
		/**********************************************************/

		
		/////////////////////////////////////////////
		/// on renomme les xxx.jar.new en xxx.jar ///
		/////////////////////////////////////////////
		
		
		
		// on verifie que le repertoire des plugins est trouve
		repertoireDesPluginsTrouve = false ;
		java.io.File repertoirePlugins = new File(InformationsSurApplicationServeur.cheminVersPlugins) ;
		if (repertoirePlugins.exists())
		{
			repertoireDesPluginsTrouve = true ;
		}else
		{
			Evenements.warning("repertoire des plugins non trouve\n pour la mise a jour des plugins ("+InformationsSurApplication.cheminVersPlugins+")") ;
		}
		
		
		String[] listeFile = null;
		// on recupere la liste de tout les plugins
		if (repertoireDesPluginsTrouve)
		{
			// tout les fichiers dans le repertoire des plugins
			listeFile = repertoirePlugins.list() ;
			// on prefixe pour obtenir un chemin complet
			for (int index=0;index<listeFile.length;index++) {
				listeFile[index]=repertoirePlugins.getAbsolutePath()+java.io.File.separatorChar+listeFile[index] ;
			}
			
			
		// on fais deux listes, une des .jar et l'autre des .jar.new
		Vector<String> listeFileJar = new Vector<String> () ;
		Vector<String> listeFileJarNew = new Vector<String> () ;
		for (String s : listeFile) {
			if (new File(s).isDirectory())
			{
				// est un repertoire
			}else
			{
				// est un fichier
				// qui a pour extention .jar
				if (new File(s).getName().endsWith(".jar"))
				{
					// l'extention est .jar
					System.out.println("fichier .jar trouve");
					listeFileJar.add(s) ;
				}
				// qui a pour extention .jar.new
				if (new File(s).getName().endsWith(".jar.new"))
				{
					// l'extention est .jar.new
					System.out.println("fichier .jar.new trouve");
					listeFileJarNew.add(s) ;
				}
			}
		}
		// maintenant il faut renommer les .jar.new en .jar,
		// mais avant il faut supprimler le .jar qui porte le meme nom.
		
		for (String sJarNew : listeFileJarNew) {
			boolean PointJarSimpleTrouve = false ;
			for (String sJar : listeFileJar) {
				if (sJarNew.equalsIgnoreCase(sJar+".new"))
				{
					System.out.println("fichier .jar.new et .jar identique");
					PointJarSimpleTrouve = true ;
					// on est ici dans la situaouttion de la presence d'un jar et jar.new identique
					// on supprime le .jar
					if (new File(sJar).delete())
					{
						System.out.println("reussit a supprimer "+sJar);
					}else
					{
						System.out.println("impossible de supprimer l'ancien .jar "+sJar);
					}
					// on renomme le .jar.new en .jar
					if (new File(sJarNew).renameTo(new File(sJar)))
					{
						System.out.println("reussit a renommer le .jar.new en Jar"+sJarNew);
					}else
					{
						System.out.println("impossible de renommer le nouveau .jar.new en .jar "+sJarNew +" en "+sJar);
					}
					
				}
			}
			if (!PointJarSimpleTrouve)
			{
				System.out.println("fichier .jar.new a renommer : "+sJarNew);
				// on a le .jar.new mais pas le .jar simple
				new File(sJarNew).renameTo(new File(sJarNew.substring(0, sJarNew.length()-4))) ;
			}
		}
		
		
		}
	
		
		
		
		/**********************************************************/
		/**********************************************************/
		/**********************************************************/
		/**********************************************************/

		
		
		
		/////////////////
		/// les menus ///
		/////////////////
		

		// on cree une JmenuBar
		JMenuBar menubar = new JMenuBar() ;
		this.setJMenuBar(menubar) ;
		
		
		
		
		// on verifie que le repertoire des plugins est trouve
		repertoireDesPluginsTrouve = false ;
		repertoirePlugins = new File(InformationsSurApplicationServeur.cheminVersPlugins) ;
		if (repertoirePlugins.exists())
		{
			repertoireDesPluginsTrouve = true ;
		}else
		{
			Evenements.warning("repertoire des plugins non trouve\n pour la generation des menus ("+InformationsSurApplication.cheminVersPlugins+")") ;
		}
		
		
		// on charge les menus.
		if (repertoireDesPluginsTrouve)
		{
			// tout les fichiers dans le repertoire des plugins
			listeFile = null ;
			listeFile = repertoirePlugins.list() ;
			// on prefixe pour obtenir un chemin complet
			for (int index=0;index<listeFile.length;index++) {
				listeFile[index]=repertoirePlugins.getAbsolutePath()+java.io.File.separatorChar+listeFile[index] ;
			}
			
			// le chargeur de menu
			ChargeurMenu chargeurDeMenu = new ChargeurMenu() ;
			
			// on lui donne a manger la liste des fichiers potentiellement plugins
			chargeurDeMenu.setFiles(listeFile) ;
			
			boolean pasDeProblemePourExtraiteLesPluginsMenus = true ;
			// le resultat de l'instantiation des plugins
			ControleurDeMenu[] listeDesInstancesDePlugins = null ;
			
			
			try {
				listeDesInstancesDePlugins = chargeurDeMenu.chargerToutLesPlugins() ;
			} catch (Exception e) {
				pasDeProblemePourExtraiteLesPluginsMenus = false ;
				Evenements.warning("erreur dans la recuperation des plugins pour les menus : "+e.getMessage());
			} ;
			
			// si on a pu recuperer les instances des plugins:
			if (pasDeProblemePourExtraiteLesPluginsMenus)
			{
				for (ControleurDeMenu i : listeDesInstancesDePlugins) {
					System.out.println("on demande de verifier la version de "+i.getNomPlugin());
					Evenements.verifierSiDerniereVersionDesPluginsMenus(i) ;
					i.setListeFonctionsDisponibles(ensembleDeFonctions) ;
					InformationsSurApplication.listePluginsChargeurDeMenu.add(i) ;
					// si on a mis au moins 1 jmenu
					if (i.ajouterALaMenuBar()!=null)
						for (JMenu menu : i.ajouterALaMenuBar()) {
							if (i!=null)
								menubar.add(menu) ;
						}
				}
			}
			
			
			
			
			// menus de debug !
		JMenu manuactions = new JMenu("Actions") ;
		JMenu menuserveur = new JMenu("Serveur") ;
		manuactions.add(menuserveur) ;
		
		
		
		
		JMenuItem serveurConfigurer = new JMenuItem("Configurer") ;
		menuserveur.add(serveurConfigurer) ;
		serveurConfigurer.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				
				new ActionConfigurerServeur(ensembleDeFonctions) ;
				
//				
//				for (String menu : ensembleDeFonctions.getVectorLibrairiepartagee()) {
//					System.out.println("lib partagee : "+menu);
//				}
//				for (ControleurDeMenu menu : ensembleDeFonctions.getVectorPluginsMenus()) {
//					System.out.println("lib menu : "+menu.getNomPlugin());
//				}
//				for (ControleurDePanneaux menu : ensembleDeFonctions.getVectorPluginsPanneau()) {
//					System.out.println("lib panneaux : "+menu.getNomPlugin());
//				}

			}}) ;
			
		
		
		JMenuItem pluginsConfigurer = new JMenuItem("Plugins") ;
		menuserveur.add(pluginsConfigurer) ;
		pluginsConfigurer.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				
				new ActionConfigurerPlugins(ensembleDeFonctions) ;
				
//				
//				for (String menu : ensembleDeFonctions.getVectorLibrairiepartagee()) {
//					System.out.println("lib partagee : "+menu);
//				}
//				for (ControleurDeMenu menu : ensembleDeFonctions.getVectorPluginsMenus()) {
//					System.out.println("lib menu : "+menu.getNomPlugin());
//				}
//				for (ControleurDePanneaux menu : ensembleDeFonctions.getVectorPluginsPanneau()) {
//					System.out.println("lib panneaux : "+menu.getNomPlugin());
//				}

			}}) ;
			

		
		
		menubar.add(manuactions) ;
	}// fin if repertoire des plugins trouve
	
		
		/**********************************************************/
		/**********************************************************/
		/**********************************************************/
		/**********************************************************/

		
		////////////////////
		/// les panneaux ///
		////////////////////
		

		
		// on place les elements :
		// le haut et le bas .
		JPanel panneauCentre = new JPanel(new BorderLayout()) ;
		this.getContentPane().add(panneauCentre,BorderLayout.CENTER) ;
		panneauCentre.add(new Zone(),BorderLayout.CENTER) ;
		

		
		
		// on verifie que le repertoire des plugins est trouve
		repertoireDesPluginsTrouve = false ;
		repertoirePlugins = new File(InformationsSurApplicationServeur.cheminVersPlugins) ;
		if (repertoirePlugins.exists())
		{
			repertoireDesPluginsTrouve = true ;
		}else
		{
			Evenements.warning("repertoire des plugins non trouve\n pour la generation des panneaux") ;
		}
		
		
		// on charge les menus.
		if (repertoireDesPluginsTrouve)
		{
			// tout les fichiers dans le repertoire des plugins
			listeFile = null ;
			listeFile = repertoirePlugins.list() ;
			// on prefixe pour obtenir un chemin complet
			for (int index=0;index<listeFile.length;index++) {
				listeFile[index]=repertoirePlugins.getAbsolutePath()+java.io.File.separatorChar+listeFile[index] ;
			}
			
			// le chargeur de panneaux
			ChargeurPanneau chargeurDePaneau = new ChargeurPanneau() ;
			
			// on lui donne a manger la liste des fichiers potentiellement plugins
			chargeurDePaneau.setFiles(listeFile) ;
			
			boolean pasDeProblemePourExtraiteLesPluginsMenus = true ;
			// le resultat de l'instantiation des plugins
			ControleurDePanneaux[] listeDesInstancesDePlugins = null ;
			
			
			try {
				listeDesInstancesDePlugins = chargeurDePaneau.chargerToutLesPlugins() ;
			} catch (Exception e) {
				pasDeProblemePourExtraiteLesPluginsMenus = false ;
				Evenements.warning("erreur dans la recuperation des plugins pour les panneaux :\n "+e.getMessage());
			} ;
			
			// si on a pu recuperer les instances des plugins:
			if (pasDeProblemePourExtraiteLesPluginsMenus)
			{
				for (ControleurDePanneaux i : listeDesInstancesDePlugins) {
					InformationsSurApplication.listePluginsChargeurDePanneaux.add(i) ;
					i.setListeFonctionsDisponibles(ensembleDeFonctions) ;
					i.executeFonctionDInitialisation() ;
				}
			}
			
		}
		
		

		
		/**********************************************************/
		/**********************************************************/
		/**********************************************************/
		/**********************************************************/

		
		///////////////////////////
		/// on lance le serveur ///
		///////////////////////////
		

		// sur le port par defaut: 4444
		ensembleDeFonctions.setPortEcoute(4444) ;
		ecouteThread = new Thread(ensembleDeFonctions.lancerServeur()) ;
		ecouteThread.start() ;

		// pour changer de port, il faudrai faire ca :
//		ensembleDeFonctions.arreterServeur() ;
//		ensembleDeFonctions.setPortEcoute(4446) ;
//		
//		ecouteThread = new Thread(ensembleDeFonctions.lancerServeur()) ;
//		ecouteThread.start() ;					

		
		
		
		
		
		
		/**********************************************************/
		/**********************************************************/
		/**********************************************************/
		/**********************************************************/

		
		/////////////////////////////
		/// fonctions d affichage ///
		/////////////////////////////
		

		
		
		
		this.setPreferredSize(new Dimension(500,300)) ;
		this.pack();
		this.setLocationRelativeTo(this.getParent());
		this.setVisible(true) ;
	}
	
	
	
	
	
	
	
	
	/**
	 * retourne l'instance de la fenetre de l'application,
	 * elle est accessible en statique .
	 * @return
	 */
	public static FenetreApplicationServeur getInstance() {
		return FenetreApplicationServeur.instanceUnique ;
	}
	
	
	
	
	/**
	 * le fenetre de confirmation aveant de sortir
	 */
	   protected void processWindowEvent(WindowEvent e) {

	        if (e.getID() == WindowEvent.WINDOW_CLOSING) {
	           Evenements.quitterLAppli() ;    
	        } else {
	            super.processWindowEvent(e);
	        }
	  }
	
}





class threadServeur {
	
	private ToutesLesMethodesServeur ensembleDeFonctions;
	private Thread lancer ;
	
	
	public void demarrer() {
		lancer = new Thread() {
			public void run() {
				if (!ensembleDeFonctions.isServeurDemarre()) {
					serveur4444() ;
				}else{
					serveur4446() ;
				}
			}
		} ;
		lancer.start() ;
		System.out.println("serveur lance !");
	}
	public void setEnsembleDeFonctions(ToutesLesMethodesServeur tlms) {
		this.ensembleDeFonctions = tlms ;
	}
	public void serveur4444() {
		System.out.println("demarrage du serveur sur 4444");
//		ensembleDeFonctions.arreterServeur() ;
		ensembleDeFonctions.setPortEcoute(4444) ;
		ensembleDeFonctions.lancerServeur() ;
	}	
	public void serveur4446() {
		System.out.println("demarrage du serveur sur 4446");
//		ensembleDeFonctions.arreterServeur() ;
		ensembleDeFonctions.setPortEcoute(4446) ;
		ensembleDeFonctions.lancerServeur() ;
	}	
	public void arreterServeur() {
		System.out.println("arret");
		ensembleDeFonctions.arreterServeur() ;
	}	
}
